home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Development Tools & Languages / Dylan Related / Mindy / Mindy 1.2 - portable sources / libraries / dylan / multilock.dylan < prev    next >
Encoding:
Text File  |  1995-03-15  |  3.1 KB  |  95 lines  |  [TEXT/ttxt]

  1. module: threads
  2. rcs-header: $Header: multilock.dylan,v 1.4 94/11/03 23:51:02 wlott Exp $
  3.  
  4. //======================================================================
  5. //
  6. // Copyright (c) 1994  Carnegie Mellon University
  7. // All rights reserved.
  8. // 
  9. // Use and copying of this software and preparation of derivative
  10. // works based on this software are permitted, including commercial
  11. // use, provided that the following conditions are observed:
  12. // 
  13. // 1. This copyright notice must be retained in full on any copies
  14. //    and on appropriate parts of any derivative works.
  15. // 2. Documentation (paper or online) accompanying any system that
  16. //    incorporates this software, or any part of it, must acknowledge
  17. //    the contribution of the Gwydion Project at Carnegie Mellon
  18. //    University.
  19. // 
  20. // This software is made available "as is".  Neither the authors nor
  21. // Carnegie Mellon University make any warranty about the software,
  22. // its performance, or its conformity to any specification.
  23. // 
  24. // Bug reports, questions, comments, and suggestions should be sent by
  25. // E-mail to the Internet address "gwydion-bugs@cs.cmu.edu".
  26. //
  27. //======================================================================
  28. //
  29. // This file contains multilocks, locks that the same thread can lock
  30. // multiple times without blocking.
  31. //
  32.  
  33. define class <multilock> (<lock>)
  34.  
  35.   // The spin lock we use to make sure operations on the multilock are
  36.   // atomic.
  37.   slot lock :: <spinlock>, setter: #f,
  38.     init-function: curry(make, <spinlock>);
  39.  
  40.   // The thread currently holding this lock, or #f if currently unlocked.
  41.   slot locker :: union(<false>, <thread>), init-value: #f;
  42.  
  43.   // The number of times the multilock has been locked by the locking
  44.   // thread.
  45.   slot count :: limited(<fixed-integer>, min: 0), init-value: 0;
  46.  
  47.   // The event we signal whenever the multilock becomes available.
  48.   slot available :: <event>, setter: #f,
  49.     init-function: curry(make, <event>);
  50. end;
  51.  
  52. define method locked? (multilock :: <multilock>) => locked? :: <boolean>;
  53.   grab-lock(multilock.lock);
  54.   let res = if (multilock.locker) #t else #f end;
  55.   release-lock(multilock.lock);
  56.   res;
  57. end;
  58.  
  59. define method grab-lock (multilock :: <multilock>) => res :: <false>;
  60.   let me = current-thread();
  61.  
  62.   grab-lock(multilock.lock);
  63.   if (multilock.locker == me)
  64.     multilock.count := multilock.count + 1;
  65.   else
  66.     while (multilock.locker)
  67.       wait-for-event(multilock.available, multilock.lock);
  68.       grab-lock(multilock.lock);
  69.     end;
  70.     multilock.locker := me;
  71.     multilock.count := 1;
  72.   end;
  73.   release-lock(multilock.lock);
  74.   #f;
  75. end;
  76.  
  77. define method release-lock (multilock :: <multilock>) => res :: <false>;
  78.   grab-lock(multilock.lock);
  79.   let locker = multilock.locker;
  80.   unless (locker)
  81.     error("%= isn't currently locked.", multilock);
  82.   end;
  83.   unless (locker == current-thread())
  84.     release-lock(multilock.lock);
  85.     error("%= attempted to unlock %=, but it is held by %=",
  86.       current-thread(), lock, locker);
  87.   end;
  88.   if (zero?(multilock.count := multilock.count - 1))
  89.     multilock.locker := #f;
  90.     signal-event(multilock.available);
  91.   end;
  92.   release-lock(multilock.lock);
  93.   #f;
  94. end;
  95.